from google.appengine.api.urlfetch import fetch as urlfetch, GET, POST
import oauthlib.oauth as oauth
import cgi
import urlparse
import urllib
import logging

class AppEngineOAuthClient(oauth.OAuthClient):

  def __init__(self, provider):
    self.consumer = oauth.OAuthConsumer(provider.consumer_key, provider.consumer_secret)
    self.sig_method = oauth.OAuthSignatureMethod_HMAC_SHA1()
    self.provider = provider

  def fetch_request_token(self):
    oauth_request = oauth.OAuthRequest.from_consumer_and_token(self.consumer, http_url=self.provider.request_token_url)
    if self.provider.scope_url:
      oauth_request.set_parameter("scope", self.provider.scope_url)
    oauth_request.sign_request(self.sig_method, self.consumer, None)

    headers = oauth_request.to_header()
    logging.info("content : %s" % headers)
    response = urlfetch(self.provider.request_token_url, method=oauth_request.http_method, headers=headers) 
    logging.info("content : %s" % response.content)
    return oauth.OAuthToken.from_string(response.content)

  def create_authorization_redirect_url(self, request_token, callback_url):
    oauth_request = oauth.OAuthRequest.from_token_and_callback(token=request_token, callback=callback_url, http_url=self.provider.authorization_url)
    return oauth_request.to_url()

  def fetch_access_token(self, token):

    logging.info("authorizd_token key : %s" % token.key)
    logging.info("authorizd_token secret : %s" % token.secret)

    oauth_request = oauth.OAuthRequest.from_consumer_and_token(self.consumer, token=token, http_url=self.provider.access_token_url)
    oauth_request.sign_request(self.sig_method, self.consumer, token)

    headers = oauth_request.to_header()
    logging.info("oauth_request_headers : %s" % headers)
    response = urlfetch(self.provider.access_token_url, method=oauth_request.http_method, headers=headers) 
    logging.info("content : %s" % response.content)
    return oauth.OAuthToken.from_string(response.content)

  def access_resource(self, access_token, request_url, request_method='GET', request_body=None):
    parameters = {}
    query_string = urlparse.urlparse(request_url)[4] # query
    query_params = cgi.parse_qs(query_string, keep_blank_values=False)
    for k, v in query_params.iteritems():
      parameters[k] = urllib.unquote(v[0])

    oauth_request = oauth.OAuthRequest.from_consumer_and_token(self.consumer, token=access_token, http_method=request_method, http_url=request_url, parameters=parameters)
    oauth_request.sign_request(self.sig_method, self.consumer, access_token)

    headers = oauth_request.to_header()
    logging.info("oauth_request_headers : %s" % headers)
    response = urlfetch(request_url, method=request_method, payload=request_body, headers=headers, follow_redirects=False)
    if response.status_code==302:
      redirect_url = response.headers.get('Location')
      logging.info("302 redirect url : %s" % redirect_url)
      return self.access_resource(access_token, redirect_url, request_method, request_body)
    else:
      return response.content

